{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Found duplicate mapnums in product - need to stitch\n",
      "stitching bond between 1 and 4 in stich has chirality STEREONONE, NONE\n",
      "stitching bond between 3 and 5 in stich has chirality STEREONONE, NONE\n",
      "stitching bond between 5 and 6 in stich has chirality STEREONONE, NONE\n",
      "Merged editable mol, converted back to real mol, [CH:1]1([NH2:4])[O:2][CH:3]1[CH:5]=[O:6]\n"
     ]
    }
   ],
   "source": [
    "from rdkit import Chem\n",
    "import rdkit.Chem.AllChem as AllChem\n",
    "# all the molecules can have saturated hydrogen connectivity at start\n",
    "smiles_list = [\"[CH:1]1[O:2][CH:3]1\", \"[CH3:1][NH2:4]\", \"[CH3:3][CH:5]=[O:6]\"]\n",
    "outcome = [Chem.MolFromSmiles(s) for s in smiles_list]\n",
    "PLEVEL = 100\n",
    "\n",
    "mapnums = [a.GetAtomMapNum() for m in outcome for a in m.GetAtoms() if a.GetAtomMapNum()]\n",
    "if len(mapnums) != len(set(mapnums)): # duplicate?\n",
    "    if PLEVEL >= 1: print('Found duplicate mapnums in product - need to stitch')\n",
    "    # need to do a fancy merge\n",
    "    merged_mol = Chem.RWMol(outcome[0])\n",
    "    merged_map_to_id = {a.GetAtomMapNum(): a.GetIdx() for a in outcome[0].GetAtoms() if a.GetAtomMapNum()}\n",
    "    for j in range(1, len(outcome)):\n",
    "        new_mol = outcome[j]\n",
    "        for a in new_mol.GetAtoms():\n",
    "            if a.GetAtomMapNum() not in merged_map_to_id:\n",
    "                merged_map_to_id[a.GetAtomMapNum()] = merged_mol.AddAtom(a)\n",
    "        for b in new_mol.GetBonds():\n",
    "            bi = b.GetBeginAtom().GetAtomMapNum()\n",
    "            bj = b.GetEndAtom().GetAtomMapNum()\n",
    "            if PLEVEL >= 10: print('stitching bond between {} and {} in stitch has chirality {}, {}'.format(\n",
    "                bi, bj, b.GetStereo(), b.GetBondDir()\n",
    "            ))\n",
    "            if not merged_mol.GetBondBetweenAtoms(\n",
    "                    merged_map_to_id[bi], merged_map_to_id[bj]):\n",
    "                merged_mol.AddBond(merged_map_to_id[bi],\n",
    "                    merged_map_to_id[bj], b.GetBondType())\n",
    "                merged_mol.GetBondBetweenAtoms(\n",
    "                    merged_map_to_id[bi], merged_map_to_id[bj]\n",
    "                ).SetStereo(b.GetStereo())\n",
    "                merged_mol.GetBondBetweenAtoms(\n",
    "                    merged_map_to_id[bi], merged_map_to_id[bj]\n",
    "                ).SetBondDir(b.GetBondDir())\n",
    "    outcome = merged_mol.GetMol()\n",
    "    if PLEVEL >= 1: print('Merged editable mol, converted back to real mol, {}'.format(Chem.MolToSmiles(outcome, True)))\n",
    "else:\n",
    "    new_outcome = outcome[0]\n",
    "    for j in range(1, len(outcome)):\n",
    "        new_outcome = AllChem.CombineMols(new_outcome, outcome[j])\n",
    "    outcome = new_outcome"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "OPENQASM 3.0;\n",
      "include \"stdgates.inc\";\n",
      "bit[3] c1;\n",
      "int switch_dummy;\n",
      "qubit[3] q1;\n",
      "switch_dummy = c1;\n",
      "switch (switch_dummy) {\n",
      "  case 0: {\n",
      "    x q1[0];\n",
      "  }\n",
      "  break;\n",
      "  case 1:\n",
      "  case 2: {\n",
      "    x q1[1];\n",
      "  }\n",
      "  break;\n",
      "  default: {\n",
      "    x q1[2];\n",
      "  }\n",
      "  break;\n",
      "}\n",
      "\n"
     ]
    }
   ],
   "source": [
    "from qiskit import qasm3, QuantumCircuit, QuantumRegister, ClassicalRegister\n",
    " \n",
    "# Build the circuit\n",
    "qreg = QuantumRegister(3)\n",
    "creg = ClassicalRegister(3)\n",
    "qc = QuantumCircuit(qreg, creg)\n",
    "with qc.switch(creg) as case:\n",
    "    with case(0):\n",
    "        qc.x(0)\n",
    "    with case(1, 2):\n",
    "        qc.x(1)\n",
    "    with case(case.DEFAULT):\n",
    "        qc.x(2)\n",
    " \n",
    "# Export to an OpenQASM 3 string.\n",
    "qasm_string = qasm3.dumps(qc, experimental=qasm3.ExperimentalFeatures.SWITCH_CASE_V1)\n",
    "print(qasm_string)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "qmg-n",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.1.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
